package org.zjvis.datascience.common.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.slf4j.MDC;
import org.zjvis.datascience.common.aspect.LogAspect;

import java.io.Serializable;

/**
 * @description 通用结果包装类
 * @date 2021-11-30
 */
@ApiModel(value = "API接口通用返回模型", description = "API接口通用返回模型")
@Data
public class ApiResult<T> implements Serializable {

    private static final long serialVersionUID = 8623317317933409279L;

    @ApiModelProperty(value = "是否成功")
    private boolean isSuccess;

    @ApiModelProperty(value = "返回信息码")
    private int code;

    @ApiModelProperty(value = "返回码")
    private String message;

    @ApiModelProperty(value = "返回提示信息")
    private String tips;

    @ApiModelProperty(value = "返回实体对象")
    private T result;

    @ApiModelProperty(value = "traceId")
    private String traceId;

    private ApiResult(boolean isSuccess, int code, String message, T result, String tips) {
        this.isSuccess = isSuccess;
        this.code = code;
        this.message = message;
        this.result = result;
        this.tips = tips;
        this.traceId = MDC.get(LogAspect.TRACE_ID);
    }

    public ApiResult() {
        this(ApiResultCode.SUCCESS.getCode(), ApiResultCode.SUCCESS.getMessage());
    }

    public ApiResult(int code, String message) {
        this(code == ApiResultCode.SUCCESS.getCode(), code, message, null, null);
    }

    public ApiResult(ApiResultCode apiResultCode, String message) {
        this(apiResultCode.getCode() == ApiResultCode.SUCCESS.getCode(), apiResultCode.getCode(), message, null, null);
    }

    public static <T> ApiResult<T> valueOf(T result) {
        return ApiResult.valueOf(ApiResultCode.SUCCESS, result);
    }

    public static <T> ApiResult<T> valueOf(ApiResultCode apiResultCode) {
        return ApiResult.valueOf(apiResultCode, null);
    }

    public static <T> ApiResult<T> valueOf(ApiResultCode apiResultCode, T result) {
        return ApiResult.valueOf(apiResultCode, result, null);
    }

    /**
     * 用于捕捉Datascience 异常 并返回异常里的描述信息
     *
     * @param apiResultCode
     * @param message
     * @param <T>
     * @return
     */
    public static <T> ApiResult<T> error(ApiResultCode apiResultCode, String message) {
        return new ApiResult<T>(false, apiResultCode.getCode(), message,
                null, "");
    }

    public static <T> ApiResult<T> error(ApiResultCode apiResultCode) {
        return new ApiResult<T>(false, apiResultCode.getCode(), apiResultCode.getMessage(),
                null, "");
    }

    /**
     * 用于捕捉Datascience 异常 并返回异常里的描述信息
     *
     * @param message
     * @param <T>
     * @return
     */
    public static <T> ApiResult<T> ok(String message) {
        return new ApiResult<T>(true, ApiResultCode.SUCCESS.getCode(), message,
                null, "");
    }

    public static <T> ApiResult<T> valueOf(ApiResultCode apiResultCode, T result, String tips) {
        if (apiResultCode == ApiResultCode.SUCCESS) {
            return new ApiResult<T>(true, apiResultCode.getCode(), apiResultCode.getMessage(),
                    result, tips);
        } else {
            return new ApiResult<T>(false, apiResultCode.getCode(), apiResultCode.getMessage(),
                    result, tips);
        }
    }

    public static <T> ApiResult<T> valueOf(Integer code, T result, String tips) {
        if (code == ApiResultCode.SUCCESS.getCode()) {
            return new ApiResult<T>(true, ApiResultCode.SUCCESS.getCode(), null,
                    result, tips);
        } else {
            return new ApiResult<T>(false, code, null,
                    result, tips);
        }
    }

}
